Categories
React Tips

React Tips — Check Why Component Rerenders, Paths, and Loading Screens

Spread the love

React is a popular library for creating web apps and mobile apps.

In this article, we’ll look at some tips for writing better React apps.

Add Dynamic Class to Manual Class Names

We can add dynamic classes with template string.

For instance, we can write:

className={`foo bar ${this.state.something}`}

where this.state.something is a string.

Also, we can use the classNames package to make setting classes dynamically easier.

For instance, we can write:

render () {
  const btnClass = classNames({
    'btn': true,
    'btn-pressed': this.state.isPressed
  });
  return <button className={btnClass}>click me</button>;
}

We call the classNames function that comes with the package and then we can set the conditions for adding the classes as the value.

The class name is in the key.

Trace Why a React Component is Re-rendering

We can write our own code to trace why a React component is re-rendering.

In a class component, we can check what values are rendered within the componentDidUpdate lifecycle method.

As its name suggests, it runs when the component is updated.

For instance, we can write:

componentDidUpdate(prevProps, prevState) {
  for (const [key, val] of Object.entries(this.props)){
     prevProps[key] !== val && console.log(`prop '${key}' changed`)
  }

  if(this.state) {
    for (const [key, val] of Object.entries(this.props)){
       prevState[key] !== val && console.log(`state'${key}' changed`)
    }
  }
}

We loop through the key-value pairs of the props and state and see what has changed.

We only log if there’re previous props or state.

If we’re using function components, we can create our own hook to log what’s changed.

For instance, we can write:

function useUpdate(props) {
  const prev = useRef(props);
  useEffect(() => {
    const changedProps = Object.entries(props).reduce((ps, [k, v]) => {
      if (prev.current[k] !== v) {
        ps[k] = [prev.current[k], v];
      }
      return ps;
    }, {});

    if (Object.keys(changedProps).length > 0) {
      console.log(changedProps);
    }
    prev.current = props;
  });
}

function App(props) {
  useUpdate(props);
  return <div>{props.children}</div>;
}

We created the useUpdate gook that use the useRef hook to get the previously stored values of the props.

Then we listen for changes to everything with the useEffect hook.

We get the changed props by looping through the props and then comparing them with the previous props we got from the useRef hook.

The props parameter has the latest props and prev has the previous props.

Then in our React component, we called our useUpdate hook with the props.

Difference Between <Route exact path=“/” /> and <Route path=“/” />

The exact prop lets us distinguish several paths that have similar names.

For instance, we can write:

<Switch>
  <Route path="/users" exact component={Users} />
  <Route path="/users/create" exact component={CreateUser} />
</Switch>

to distinguish between the /users and /users/create routes.

If we don’t have exact , then /users/create will be matched with the /users route.

Loop and Render elements in React.js Without an Array of Objects to Map

If we want to render an object’s properties to a list, we can use the Object.entries and array’s map methods.

For instance, we can write:

render() {
  return (
     <div>
       {obj && Object.entries(obj).map(([key, value], index) => {
          return <span key={index}>{value}</span>;
       }.bind(this))}
     </div>
  );
}

In our render method, we used Object.entries to get the key-value pairs of the object as an array.

Then we called map to render each property value into a span.

Display Loading Screen While DOM is Rendering

We can display a loading screen by setting the loading state in a component.

For instance, we can write:

import React, { useState, useEffect } from 'react';

const App = () => {
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    setTimeout(() => setLoading(false), 1000)
  }, []);

  return !loading && <div>hello world</div>;
};

We have the loading state and setLoading function returned by the useState hook.

We set it to true initially to see our loading message.

Then we use the useEffect hook to set the loading state to false as the content is loaded.

Then we can render the content we want when the loading state is false .

Conclusion

We can use the exact prop in React Router to match the routes exactly.

We can set a loading state to make it display.

Dynamic classes can be set with string interpretation of the classnames package.

We can watch for props and state changes in our components to see why our component is re-rendering.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *